package com.huadao.cart_ccs.experiment.log.paramsAnysis;

import android.graphics.Color;
import android.os.Bundle;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.huadao.cart_ccs.R;
import com.huadao.cart_ccs.base.BaseFragment;
import com.huadao.cart_ccs.base.BasePresenter;
import com.huadao.cart_ccs.experiment.log.OnDay;
import com.huadao.cart_ccs.common.TemperatureMarkerView;
import com.huadao.cart_ccs.common.UtilHelpers;
import com.huadao.cart_ccs.common.deviceController.O2Controller;
import com.huadao.cart_ccs.common.deviceController.TemperatureController;
import com.huadao.cart_ccs.common.deviceController.CO2Controller;

import butterknife.BindView;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

public class ParamsAnysisFrag extends BaseFragment implements OnDay, IParamsAnysisContract.IParamsAnysisView {
    @BindView(R.id.chart_CO2)
    LineChart chartCO2;
    @BindView(R.id.chart_O2)
    LineChart chartO2;
    @BindView(R.id.chart_temperature)
    LineChart chartTemperature;

    private Disposable CO2_disposable;
    private Disposable O2_disposable;
    private Disposable temperature_disposable;

    private ParamsAnysisPresenter paramsAnysisPresenter;

    public static ParamsAnysisFrag getInstance(int day) {
        Bundle bundle = new Bundle();
        bundle.putInt("day", day);
        ParamsAnysisFrag paramsAnysisFrag = new ParamsAnysisFrag();
        paramsAnysisFrag.setArguments(bundle);
        return paramsAnysisFrag;
    }

    @Override
    public int getContentViewId() {
        return R.layout.frag_params_anysis;
    }

    @Override
    protected void initAllMembersView(Bundle savedInstanceState) {
        paramsAnysisPresenter = new ParamsAnysisPresenter(this);
        Bundle bundle = getArguments();
        if (bundle != null && bundle.containsKey("day")) {
            int day = bundle.getInt("day");
            paramsAnysisPresenter.setDay(day);
        }
        initChart(chartCO2);
            setLimitLine(chartCO2, (float) CO2Controller.getInstance().getSettedValue().floatValue());

        initChart(chartO2);
        setLimitLine(chartO2, (float) O2Controller.getInstance().getSettedValue().floatValue());

        initChart(chartTemperature);
        setLimitLine(chartTemperature, (float) TemperatureController.getInstance().getSettedValue().floatValue());

        setLineChartData();
    }

    private void setLineChartData() {
        CO2_disposable=Observable.create(new ObservableOnSubscribe<LineData>() {
            @Override
            public void subscribe(ObservableEmitter<LineData> emitter) throws Exception {
                LineData CO2Data = paramsAnysisPresenter.getCo2Data();
                emitter.onNext(CO2Data);
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<LineData>() {
                    @Override
                    public void accept(LineData lineData) throws Exception {
                        if (lineData.getEntryCount() != 0) {
                            setChartData(chartCO2, lineData);
                        } else {
                            chartCO2.clear();
                        }
                    }
                });

        O2_disposable=Observable.create(new ObservableOnSubscribe<LineData>() {
            @Override
            public void subscribe(ObservableEmitter<LineData> emitter) throws Exception {
                LineData O2Data = paramsAnysisPresenter.getO2Data();
                emitter.onNext(O2Data);
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<LineData>() {
                    @Override
                    public void accept(LineData lineData) throws Exception {
                        if (lineData.getEntryCount() != 0) {
                            setChartData(chartO2, lineData);
                        } else {
                            chartO2.clear();
                        }
                    }
                });

        temperature_disposable=Observable.create(new ObservableOnSubscribe<LineData>() {
            @Override
            public void subscribe(ObservableEmitter<LineData> emitter) throws Exception {
                LineData temperatureData = paramsAnysisPresenter.getTemperatureData();
                emitter.onNext(temperatureData);
            }
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<LineData>() {
                    @Override
                    public void accept(LineData lineData) throws Exception {
                        if (lineData.getEntryCount() != 0) {
                            setChartData(chartTemperature, lineData);
                        } else {
                            chartTemperature.clear();
                        }
                    }
                });
    }

    @Override
    protected BasePresenter getPresenter() {
        return paramsAnysisPresenter;
    }

    private void initChart(LineChart lineChart) {
        XAxis xAxis = lineChart.getXAxis();
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                return UtilHelpers.getTime(value);
            }
        });
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setDrawGridLines(false);

        // 图表左边的y坐标轴线
        YAxis leftAxis = lineChart.getAxisLeft();
        leftAxis.setDrawGridLines(false);

        YAxis rightAxis = lineChart.getAxisRight();
        // 不显示图表的右边y坐标轴线
        rightAxis.setEnabled(false);

        lineChart.getAxisRight().setEnabled(false);

        TemperatureMarkerView temperatureMarkerView = new TemperatureMarkerView(this.getContext(), R.layout.markerview_temperature);
        temperatureMarkerView.setChartView(lineChart);
        lineChart.setMarker(temperatureMarkerView);

        lineChart.getDescription().setText("时间");
        lineChart.setNoDataText("没有数据");
        lineChart.setScaleXEnabled(true);
        lineChart.setScaleYEnabled(false);
    }

    private void setLimitLine(LineChart lineChart, float limitValue) {
        YAxis leftAxis = lineChart.getAxisLeft();
        leftAxis.removeAllLimitLines();

        LimitLine settingTemperatureLine = new LimitLine(limitValue, String.valueOf(limitValue));
        settingTemperatureLine.setLineWidth(4f);
        settingTemperatureLine.enableDashedLine(10f, 10f, 0f);
        settingTemperatureLine.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_TOP);
        settingTemperatureLine.setTextSize(10f);
        settingTemperatureLine.setTextColor(Color.BLACK);
        settingTemperatureLine.setLineColor(getResources().getColor(R.color.limit_line));
        leftAxis.addLimitLine(settingTemperatureLine);
        leftAxis.setDrawLimitLinesBehindData(true);
        lineChart.invalidate();
    }

    private void setChartData(LineChart lineChart, LineData lineData) {
        lineChart.setData(lineData);
//        //设置一页最大显示个数为1000，超出部分就滑动
//        float ratio = (float) lineData.getEntryCount() / (float) 1000;
//        //resetZoom
//        lineChart.fitScreen();
//        //显示的时候是按照多大的比率缩放显示,1f表示不放大缩小
//        lineChart.zoom(ratio, 1f, 0, 0);
//        //从最后一个数据查看
//        lineChart.moveViewToX(lineData.getXMax());
//        //设置XY轴动画.由于线程不安全，在动画过程中改变数据会崩，所以还是不用动画了
//        lineChart.animateXY(1500, 1500, Easing.EasingOption.EaseInSine, Easing.EasingOption.EaseInSine);
        lineChart.invalidate();
    }

    @Override
    public void notifyCo2Chart() {
        chartCO2.notifyDataSetChanged(); // let the chart know it's data changed
        chartCO2.invalidate(); // refresh
    }

    @Override
    public void notifyO2Chart() {
        chartO2.notifyDataSetChanged(); // let the chart know it's data changed
        chartO2.invalidate(); // refresh
    }

    @Override
    public void notifyTemperatureChart() {
        chartTemperature.notifyDataSetChanged(); // let the chart know it's data changed
        chartTemperature.invalidate(); // refresh
    }

    @Override
    public void daySelected(int day) {
        if(CO2_disposable!=null) {
            CO2_disposable.dispose();
        }
        if(O2_disposable!=null) {
            O2_disposable.dispose();
        }
        if(temperature_disposable!=null) {
            temperature_disposable.dispose();
        }
        if (day != paramsAnysisPresenter.getDay()) {
            paramsAnysisPresenter.setDay(day);
            setLineChartData();
        }
    }

    @Override
    public void clearTemperatureChart() {
        chartTemperature.clear();
    }

    @Override
    public void clearCO2Chart() {
        chartCO2.clear();
    }

    @Override
    public void clearO2Chart() {
        chartO2.clear();
    }

    @Override
    public void onDestroy() {
        if(CO2_disposable!=null) {
            CO2_disposable.dispose();
        }
        if(O2_disposable!=null) {
            O2_disposable.dispose();
        }
        if(temperature_disposable!=null) {
            temperature_disposable.dispose();
        }
        super.onDestroy();
    }
}
